#include "_socket.h"
#include "errno.h"
#include "unistd.h"
#include "logManager.h"

void tcp_socket::__setFdForPrivate(int fd){
	netfd = fd;
}

int tcp_socket::open(){

	netfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if( netfd < 0 ){
		return -2;
	}
	return netfd;
}

int tcp_socket::setNonBlock(){
	
	int flags = ::fcntl(netfd, F_GETFL);  
    flags |= O_NONBLOCK;  
    fcntl(netfd, F_SETFL, flags);  
	return 0;
}

int tcp_socket::setTimeOut(int ms = 200){
	struct timeval tv;
    tv.tv_sec = ms / 1000;
    tv.tv_usec = (ms % 1000) * 1000;
    setsockopt(netfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
    setsockopt(netfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
	return 0;
}


int tcp_socket::connect(const char *ip, int port){

	struct sockaddr_in server_addr;
	bzero(&server_addr,sizeof(struct sockaddr_in));  
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr = inet_addr(ip);
	server_addr.sin_port = htons(port); 	
	
	if( ::connect(netfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr)) < 0 ){
		return -1;
	}
	return 0;
}

int tcp_socket::send(const char* buf, int size){
	
	int ret = ::send(netfd, buf, size, 0);
	if( ret < 0 ){
		if(errno == EINTR || errno == EAGAIN || errno == EINPROGRESS){
			return 0;
		}
	}
	return ret;
}

int tcp_socket::recv(char* buf, int size){
	recvStatus = 0;//0 can not deal; -1 fin; -2 error
	int ret = ::recv(netfd, buf, size, 0);
	if( ret < 0 ){
		if(errno == EINTR || errno == EAGAIN || errno == EINPROGRESS){
			recvStatus = 0;
			return 0;
		}
		recvStatus = -2;
	}
	if( ret == 0 ){
		recvStatus = -1;//fin
	}
	return ret;
}

int tcp_socket::close(){
	if( netfd >= 0 ){
		::close(netfd);
	}
	netfd = -1;
	return 0;
}

